package cn.edu.xmu.oomall.comment.dao.bo;
import cn.edu.xmu.javaee.core.aop.CopyFrom;
import cn.edu.xmu.javaee.core.exception.BusinessException;
import cn.edu.xmu.javaee.core.model.ReturnNo;
import cn.edu.xmu.javaee.core.model.bo.OOMallObject;
import cn.edu.xmu.javaee.core.model.dto.UserDto;
import cn.edu.xmu.oomall.comment.controller.dto.CommentDto;
import cn.edu.xmu.oomall.comment.dao.CommentDao;
import cn.edu.xmu.oomall.comment.mapper.po.CommentPo;
import cn.edu.xmu.oomall.comment.mapper.po.OrderItemPo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.*;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@AllArgsConstructor
@NoArgsConstructor
@ToString(callSuper = true, doNotUseGetters = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@CopyFrom({CommentPo.class, CommentDto.class})
public class Comment extends OOMallObject implements Serializable {

    /**
     * 评论的父评论id
     */
    public static final Long  PARENT_ID = 0L;

    /**
     *三种状态
     */
//    待审核
    public static final Byte PENDING = 0;

//    审核通过
    public static final Byte ACCEPT = 1;

//    审核未通过
    public static final Byte REJECT = 2;

    /**
     * 评论类型
     */
//    主评论
    public static final Byte MAIN = 0;

//    回复评论
    public static final Byte REPLY = 1;


    public static final Map<Byte,String> STATUSNAMES = new HashMap<>(){
        {
            put(PENDING, "待审核");
            put(ACCEPT, "审核通过");
            put(REJECT, "审核未通过");
        }
    };


    public static final Map<Byte,String> TYPENAMES = new HashMap<>(){
        {
            put(MAIN, "主评论");
            put(REPLY, "回复评论");
        }
    };

    /**
     * 允许的状态迁移
     */

    public static final Map<Byte, Set<Byte>> toStatus = new HashMap<>(){
        {
            put(PENDING, new HashSet<>() {
                {
                    add(ACCEPT);
                    add(REJECT);
                }
            });
        }
    };

    @Setter
    @ToString.Exclude
    @JsonIgnore
    protected CommentDao commentDao;

    public String getStatusName(){
        return STATUSNAMES.get(this.status);
    }

    protected Long pid;
    protected Long customerId;
    protected String content;
    protected Long shopId;
    protected Long orderItemId;
    protected Byte status;
    protected Byte type;
    protected Long productId;

    public Comment reviewComment(Comment comment, UserDto user) {
        if(Comment.toStatus.get(this.status).contains(comment.status)){
            this.status = comment.status;
            this.setModifier(user);
            this.setGmtModified(LocalDateTime.now());
            return commentDao.save(this);
        }else{
            throw new BusinessException(ReturnNo.STATENOTALLOW, String.format(ReturnNo.STATENOTALLOW.getMessage(), "评论", id));
        }
    }

    public Comment replyComment(Comment replyComment, UserDto user) {
        replyComment.setCustomerId(this.customerId);
        replyComment.setShopId(user.getId());
        replyComment.setOrderItemId(this.orderItemId);
        replyComment.setProductId(this.productId);
        replyComment.setCreator(user);
        replyComment.setGmtCreate(LocalDateTime.now());
        return commentDao.insert(replyComment);
    }

    public Long getProductId() {
        return productId;
    }

    public void setProductId(Long productId) {
        this.productId = productId;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getCreatorName() {
        return creatorName;
    }

    public void setCreatorName(String creatorName) {
        this.creatorName = creatorName;
    }

    public Long getCustomerId() {
        return customerId;
    }

    public void setCustomerId(Long customerId) {
        this.customerId = customerId;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Long getShopId() {
        return shopId;
    }

    public void setShopId(Long shopId) {
        this.shopId = shopId;
    }

    public Long getOrderItemId() {
        return orderItemId;
    }

    public void setOrderItemId(Long orderItemId) {
        this.orderItemId = orderItemId;
    }

    public Byte getStatus() {
        return status;
    }

    public void setStatus(Byte status) {
        this.status = status;
    }

    public LocalDateTime getGmtCreate() {
        return gmtCreate;
    }

    public void setGmtCreate(LocalDateTime gmtCreate) {
        this.gmtCreate = gmtCreate;
    }

    public LocalDateTime getGmtModified() {
        return gmtModified;
    }

    public void setGmtModified(LocalDateTime gmtModified) {
        this.gmtModified = gmtModified;
    }

    public Byte getType() {
        return type;
    }

    public void setType(Byte type) {
        this.type = type;
    }

    public Long getPid() {
        return pid;
    }

    public void setPid(Long pid) {
        this.pid = pid;
    }

    public void setCreatorId(Long creatorId) {
        this.creatorId = creatorId;
    }

    public Long getCreatorId() {
        return creatorId;
    }

    public void setModifierId(Long modifierId) {
        this.modifierId = modifierId;
    }

    public Long getModifierId() {
        return modifierId;
    }

    public String getModifierName() {
        return modifierName;
    }

    public void setModifierName(String modifierName) {
        this.modifierName = modifierName;
    }
}
